﻿using UnityEngine;

public abstract class HorizontalOrVerticalScrollListCreator : BaseScrollListCreator
{
    // 布局间隔
    protected float spacing;
    protected RectOffset padding;

    public override Vector2 Spacing => Vector2.one * spacing;

    protected abstract RectTransform RecycleBeginToEnd();

    protected abstract RectTransform RecycleEndToBegin();

    protected abstract RectTransform NewBefore();

    protected abstract RectTransform NewNext();

    public abstract bool IsCanRecycleBegin();

    public abstract bool IsCanRecycleEnd();

    public override bool TryCreateNext(out RectTransform item, CreatorTool? tool)
    {
        item = null;

        var type = RecycleType.None;
        if (IsNeedCreateNext())
        {
            if (IsCanRecycleBegin())
                type = RecycleType.RecycleBegin;
            else
                type = RecycleType.NewNext;
        }
        else
        {
            return false;
        }

        item = GetItem(type);
        if (item == null)
            return false;

        UpdateActiveList();

        return true;
    }

    public override bool TryCreateBefore(out RectTransform item, CreatorTool? tool)
    {
        item = null;

        var type = RecycleType.None;
        if (IsNeedCreateBefore())
        {
            if (IsCanRecycleEnd())
                type = RecycleType.RecycleEnd;
            else
                type = RecycleType.NewBefore;
        }
        else
        {
            return false;
        }

        item = GetItem(type);
        if (item == null)
            return false;

        UpdateActiveList();

        return true;
    }

    public override bool TryGetItemByChildIndex(int childIndex, out RectTransform item)
    {
        item = null;

        if (childIndex >= activeList.Count || childIndex < 0)
            return false;

        item = activeList[childIndex];
        return true;
    }

    public override bool TryInsertItem(int childIndex, out RectTransform item)
    {
        item = null;

        if (childIndex >= activeList.Count || childIndex < 0)
            return false;

        if (IsCanRecycleEnd())
            item = GetItem(RecycleType.RecycleInsert);
        else
            item = GetItem(RecycleType.NewNext);

        var unactivatedCount = GetUnactivatedCount(childIndex);
        var itemIndex = childIndex + unactivatedCount;

        item.SetSiblingIndex(itemIndex);

        UpdateActiveList();

        return true;
    }

    public override void TryRemoveItem(int childIndex)
    {
        if (childIndex >= activeList.Count || childIndex < 0)
            return;

        RecycleItem(childIndex, activeList[childIndex]);
        m_lastItemChange(-1);

        UpdateActiveList();
    }

    private RectTransform GetItem(RecycleType type)
    {
        RectTransform item = null;
        switch (type)
        {
            case RecycleType.RecycleBegin:
                item = RecycleBeginToEnd();
                m_lastItemChange(1);
                break;
            case RecycleType.RecycleEnd:
                item = RecycleEndToBegin();
                m_lastItemChange(-1);
                break;
            case RecycleType.RecycleInsert:
                item = activeList[activeList.Count - 1];
                m_recycleItem(activeList.Count - 1, item);
                break;
            case RecycleType.NewNext:
                item = NewNext();
                m_lastItemChange(1);
                break;
            case RecycleType.NewBefore:
                item = NewBefore();
                break;
        }

        return item;
    }

    public enum RecycleType
    {
        /// <summary>
        /// 不需要创建
        /// </summary>
        None,
        /// <summary>
        /// 实例化一个新的，添加到末尾
        /// </summary>
        NewNext,
        /// <summary>
        /// 实例化一个新的，添加到开头
        /// </summary>
        NewBefore,
        /// <summary>
        /// 回收现有控件，并插入到某一个位置
        /// </summary>
        RecycleInsert,
        /// <summary>
        /// 回收开头控件
        /// </summary>
        RecycleBegin,
        /// <summary>
        /// 回收末尾控件
        /// </summary>
        RecycleEnd,
    }
}